/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package datenbank;

import java.sql.*;
import java.util.Vector;
import data.*;


/**
 *
 * @author Daniel
 */
public class TischMapper {

    private static TischMapper tischMapper = null;

    /*
     * statische Methode, die sicherstellt, dass nur eine Istanz von TischMapper erzeugt wird.
     *
     * @return Das produktMapper -Objekt.
     */
    public static TischMapper tischMapper() {
        if (tischMapper == null) {
            tischMapper = new TischMapper();
        }

        return tischMapper;
    }
    /**
    * Hier wird ein neues Tisch (-Objekt) in die Datenbank eingefügt.
    * Dabei wird auch überprüft was die bisher höhste tisch_id(der Primärschlüssel) ist.
    *
    * @param ti ist das das zu speichernde Tisch-Objekt
    * @return das bereits übergebene Objekt, jedoch mit ggf. korrigierter tisch_id vom Typ Tisch
    */

    public Tisch insert(Tisch ti) {
        Connection con = DBConnection.connection();

        try {
            Statement stmt = con.createStatement();

            /*
             * Hier wird überprüft welche tisch_id bisher die höhste ist.
             */
            ResultSet rs = stmt.executeQuery(
                    "SELECT MAX(tisch_id) AS maxid " +
                    "FROM Tisch");


            if (rs.next()) {
                try {
                    /* Hier wird die bisher höhste vorhandene tisch_id um +1 erhöht.
                     */
                    ti.set_tisch_id(rs.getInt("maxid") + 1);

                    stmt = con.createStatement();

                    /* Die tatsächliche Einfügeoperation mit den übergebenden Attributen.
                     */
                    stmt.executeUpdate("INSERT INTO Tisch (tisch_id,tisch_nr,kapazitaet,raum) " +
                            "VALUES (" +
                            ti.get_tisch_id() + "," +
                            ti.get_tisch_nr() + "," +
                            ti.get_kapazitaet() + ",'" +
                            ti.get_raum() + "')");


                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        } catch (SQLException e2) {
            e2.printStackTrace();
        }
        /* Rückgabe des angelegten Objekts ti von Typ Tisch.
         */
        return ti;
    }


    public Tisch update(Tisch ti) {
        /* Stellt durch Aufruf der connection() Methode der DBConnection-Klasse, die Verbindung zur Datenbank her. */
        Connection con = DBConnection.connection();

        try {
            // Leeres SQL-Statement stmt wird angelegt.
            Statement stmt = con.createStatement();

            //Statement wird ausgefüllt und als Query an die DB geschickt.
            stmt.executeUpdate("UPDATE Tisch " +
                    "SET tisch_id=" + ti.get_tisch_id() + "," +
                    "tisch_nr=" + ti.get_tisch_nr() + "," +
                    "kapazitaet=" + ti.get_kapazitaet() + "," +
                    "raum='" + ti.get_raum() + "' " +
                    "WHERE tisch_id=" + ti.get_tisch_id());

        } catch (SQLException e2) {
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // das als Parameter übergebende Objekt des Typs Tisch wird zurückgegeben
        return ti;
    }


    /**
     * Diese Methode löscht alle Daten eines Tisch- Objekts aus der Datenbank.
     *
     * @param ti ist das zu löschende Objekt
     */

    public void delete(Tisch ti) {
        Connection con = DBConnection.connection();

        try {
            // Leeres SQL-Statement stmt wird angelegt.
            Statement stmt = con.createStatement();

            // Statement wird ausgefüllt und als Query an die DB geschickt.
            stmt.executeUpdate("DELETE FROM Tisch " +
                    "WHERE tisch_id=" + ti.get_tisch_id());

        } catch (SQLException e2) {
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /*
     * Bei dieser Methode werden alle Tische ausgelesen.
     *
     * @return Es wird ein Vektor mit Tisch-Objekten, d.h. allen in der Datenbank angelegte Tische, zurückgegeben.
     * Bei evtl. Exceptions wird ein partiell gefüllter oder ggf.
     * auch leerer Vektor vom Typ Tisch zurückgeliefert.
     */

    public Vector<Tisch> findAll() {
        Connection con = DBConnection.connection();
        Vector<Tisch> result = new Vector<Tisch>();

        try {
            Statement stmt = con.createStatement();

           
            ResultSet rs = stmt.executeQuery(
                    "SELECT tisch_id, tisch_nr, kapazitaet, raum " +
                    "FROM Tisch " +
                    "ORDER BY tisch_id");

            // Für jeden Eintrag im Suchergebnis wird nun ein Tisch-Objekt ti erstellt.
            while (rs.next()) {
                try {
                    TischImpl ti = new TischImpl();
                    ti.set_tisch_id(rs.getInt("tisch_id"));
                    ti.set_tisch_nr(rs.getInt("tisch_nr"));
                    ti.set_kapazitaet(rs.getInt("kapazitaet"));
                    ti.set_raum(rs.getString("raum"));
                    //Hier wird das Objekt dem Ergebnisvektor hinzugefügt
                    result.addElement(ti);
                } catch (Exception e) {
                    e.printStackTrace();
                    //Bei einer evtl. Exception wird die while-Schleife abgebrochen.
                    break;
                }
            }
        } catch (SQLException e2) {
            e2.printStackTrace();
        }
        // Ergebnisvektor vom Typ Tisch wird zurückgeben.
        return result;
    }


    /**
     * Diese Methode sucht die Datenbank nach einem Tisch mit eingegebener ID.
     *
     * @param tisch_id ist das Primärschlüsselattribut Tisch in der Datenbank.
     * @return Das Objekt vom Typ Tisch, das der id entspricht wird zurückgegebn.
     * null wird zurückgegeben, wenn das Objekt nicht in der Datenbank vorhanden ist.
     * Da es sich um einen Primärschlüssel handelt und dieser somit eindeutig ist, wird genau ein Objekt zurückgegeben.
     */

    public Tisch findbyid(int id) {
        Connection con = DBConnection.connection();

        try {
            Statement stmt = con.createStatement();
            
            ResultSet rs = stmt.executeQuery(
                    "SELECT tisch_id, tisch_nr, kapazitaet, raum FROM Tisch " +
                    "WHERE tisch_id =" + id +
                    " ORDER BY tisch_id");

            /*
             * Da es sich bei id um einen Primärschlüssel handelt, kann max. nur ein Tupel zurückgegeben werden.
             * Es wird geprüft, ob ein Ergebnis vorliegt. Wenn ja werden die Attribute tisch_id,
             * tisch_nr, kapazitaet und raum ausgelesen und als Typ Tisch zurückgegeben.
             */
            if (rs.next()) {
                try {

                    TischImpl ti = new TischImpl();
                    ti.set_tisch_id(rs.getInt("tisch_id"));
                    ti.set_tisch_nr(rs.getInt("tisch_nr"));
                    ti.set_kapazitaet(rs.getInt("kapazitaet"));
                    ti.set_raum(rs.getString("raum"));
                    return ti;

                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
        } catch (SQLException e2) {
            e2.printStackTrace();
            return null;
        }

        return null;
    }
}
